#include "StdAfx.h"
#include "RibbonResultManagerView.h"
#include "Resource.h"
#include "Util.h"
#include "RibbonCommandItem.h"
#include <algorithm>
#include <functional>
#include <vector>
#include "PropertyKeyItem.h"
#include "ComboBoxTextItem.h"
#include "PropertyReader.h"
#include <set>

using namespace std;
using namespace std::tr1;
using namespace std::tr1::placeholders;

extern wchar_t g_sUICCPath[MAX_PATH];
extern wchar_t g_sRCPath[MAX_PATH];
extern wchar_t g_sLINKPath[MAX_PATH];

CRibbonResultManagerView *CRibbonResultManagerView ::s_pRibbonResultManagerView = 0;

CRibbonResultManagerView::CRibbonResultManagerView(void) : m_currentApplicationMode(0), m_bLoadEnabled(false)
{
	if (s_pRibbonResultManagerView != 0)
		throw L"Only one RibbonResultManagerView is allowed";
	s_pRibbonResultManagerView = this;
}

CRibbonResultManagerView::~CRibbonResultManagerView(void)
{
	FreeLibrary(m_hRibbonResourseModule);
	m_hRibbonResourseModule = 0;
	s_pRibbonResultManagerView = 0;
}

void CRibbonResultManagerView::OnClose()
{
	DestroyWindow(m_hWnd);
}

void CRibbonResultManagerView::SetParameters(const shared_ptr<CRibbonInfo> &ribbonInfo, const wstring &szResourceDllName, PCWSTR szRibbonResourceName)
{
	m_ribbonInfo = ribbonInfo;
	m_szResourceDllName = szResourceDllName;
	m_szRibbonResourceName = szRibbonResourceName;
}

HRESULT CRibbonResultManagerView::OnAfterCreateRibbon(HWND hWnd, HINSTANCE hInstance)
{
	m_hWnd = hWnd;
	m_hRibbonResourseModule = LoadLibraryEx(m_szResourceDllName.c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES 
		| LOAD_IGNORE_CODE_AUTHZ_LEVEL | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);

	if (m_hRibbonResourseModule == NULL)
		return E_FAIL;
	
	CRibbonResultView::RegisterClass(hInstance);
	RECT rect;
	GetClientRect(hWnd, &rect);

	POINT topLeft = {rect.left, rect.top};
	POINT bottomRight = {rect.right, rect.bottom};
	ClientToScreen(hWnd, &topLeft);
	ClientToScreen(hWnd, &bottomRight);

	UINT32 height;
	GetRibbonHeight(&height);

	m_hRibbonResultViewWnd = CreateWindowEx(0,RIBBONRESULTVIEW_WNDCLASS, L"Ribbon Result", WS_OVERLAPPEDWINDOW,
		topLeft.x, topLeft.y + height, bottomRight.x - topLeft.x, bottomRight.y - (topLeft.y + height), hWnd, NULL, hInstance, NULL);
		
	RECT rectResult;
	GetWindowRect(m_hRibbonResultViewWnd, &rectResult);
	GetWindowRect(hWnd, &rect);
	SetWindowPos(hWnd, m_hRibbonResultViewWnd, rectResult.left, rect.top, rectResult.right - rectResult.left, height * 3, SWP_NOMOVE);

	m_pRibbonResultView = NULL;
	CComObject<CRibbonResultView>::CreateInstance(&m_pRibbonResultView);
	m_pRibbonResultView->SetRibbonInfo(m_ribbonInfo);
	m_pRibbonResultView->RegisterForCloseEvent(this);

	return CRibbonResultView::Create(m_pRibbonResultView, m_hRibbonResultViewWnd, hInstance, m_hRibbonResourseModule, m_szRibbonResourceName);
}

HRESULT CRibbonResultManagerView::OnViewChanged(UINT32 nViewID, __in UI_VIEWTYPE typeID, __in IUnknown* pView, UI_VIEWVERB verb, INT32 uReasonCode)
{
	if (typeID != UI_VIEWTYPE_RIBBON && verb != UI_VIEWVERB_CREATE)
		return E_NOTIMPL;

	CComObject<CRibbonColorSetter>::CreateInstance(&m_pBackgroundColor); 
	m_pBackgroundColor->Initialize(UI_PKEY_GlobalBackgroundColor, m_pUIFramework);

	CComObject<CRibbonColorSetter>::CreateInstance(&m_pHighlightColor); 
	m_pHighlightColor->Initialize(UI_PKEY_GlobalHighlightColor, m_pUIFramework);
	
	CComObject<CRibbonColorSetter>::CreateInstance(&m_pTextColor); 
	m_pTextColor->Initialize(UI_PKEY_GlobalTextColor, m_pUIFramework);
	
	return S_OK;
}


HRESULT CRibbonResultManagerView::OnCreateUICommand(UINT32 nCmdID, __in UI_COMMANDTYPE typeID, __deref_out IUICommandHandler** ppCommandHandler) 
{
	if (nCmdID == cmdBackgroundColor)
	{
		return m_pBackgroundColor->QueryInterface(__uuidof(IUICommandHandler), (void**)ppCommandHandler);
	}

	if (nCmdID == cmdHighlightColor)
	{
		return m_pHighlightColor->QueryInterface(__uuidof(IUICommandHandler), (void**)ppCommandHandler);
	}
	
	if (nCmdID == cmdTextColor)
	{
		return m_pTextColor->QueryInterface(__uuidof(IUICommandHandler), (void**)ppCommandHandler);
	}

	return QueryInterface(__uuidof(IUICommandHandler), (void**)ppCommandHandler);
}


HRESULT CRibbonResultManagerView::Execute(UINT nCmdID,
		UI_EXECUTIONVERB verb, 
		__in_opt const PROPERTYKEY* key,
		__in_opt const PROPVARIANT* ppropvarValue,
		__in_opt IUISimplePropertySet* pCommandExecutionProperties)
{
	//For now we dont need to handle preview
	if (verb != UI_EXECUTIONVERB_EXECUTE)
		return S_OK;

	if (nCmdID == cmdCommandSelection)
	{
		IRibbonCommandItem *ribbonCommandItem;
		HRESULT hr = pCommandExecutionProperties->QueryInterface(IID_PPV_ARGS(&ribbonCommandItem));
		if (SUCCEEDED(hr))
		{
			ribbonCommandItem->GetCommandId(&m_currentCommandItemId);
			ribbonCommandItem->Release();
			return S_OK;
		}
	}

	if (nCmdID == cmdPropertyKeySelection)
	{
		IPropertyKeyItem *propertyKeyItem;
		HRESULT hr = pCommandExecutionProperties->QueryInterface(IID_PPV_ARGS(&propertyKeyItem));
		if (SUCCEEDED(hr))
		{
			propertyKeyItem->GetPropertyKey(&m_currentPropertyKey);
			propertyKeyItem->Release();
			return S_OK;
		}
	}

	if (nCmdID == cmdInvalidateState || nCmdID == cmdInvalidateProperty || nCmdID == cmdInvalidateValue || nCmdID == cmdInvalidateAllProperty)
	{
		UI_INVALIDATIONS flag = 
			(nCmdID == cmdInvalidateState) ? UI_INVALIDATIONS_STATE :
			(nCmdID == cmdInvalidateProperty) ?  UI_INVALIDATIONS_PROPERTY :
			(nCmdID == cmdInvalidateValue) ? UI_INVALIDATIONS_VALUE : 
			UI_INVALIDATIONS_ALLPROPERTIES;
		
		wostringstream text;
		text << L"Invalidating command: " <<  m_ribbonInfo->GetCommandNameById(m_currentCommandItemId) <<
			L"  Property: " << CPropertyKeyItem::GetPropertyKeyName(m_currentPropertyKey) << endl;


		m_pRibbonResultView->AppendText(text.str());
		HRESULT hr = m_pRibbonResultView->InvalidateUICommand(m_currentCommandItemId, flag, &m_currentPropertyKey);

		if (FAILED(hr))
		{
			text.clear();
			text << L"Failed to invalidating command: " <<  m_ribbonInfo->GetCommandNameById(m_currentCommandItemId) <<
				L" with property: " << CPropertyKeyItem::GetPropertyKeyName(m_currentPropertyKey) << endl;
			m_pRibbonResultView->AppendText(text.str());
		}
		return S_OK;
	}

	if (nCmdID == cmdGetProperty)
	{
		wostringstream text;
		PROPVARIANT propVariant;
		HRESULT hr = m_pRibbonResultView->GetUICommandProperty(m_currentCommandItemId, m_currentPropertyKey, &propVariant);
		
		if (FAILED(hr))
		{
			text << L"Failed to get propety: " << CPropertyKeyItem::GetPropertyKeyName(m_currentPropertyKey) <<
				L" of command: " << m_ribbonInfo->GetCommandNameById(m_currentCommandItemId) << endl;
		}
		else
		{
			shared_ptr<CProperty> prop = m_propertyReader.Parse(&m_currentPropertyKey, &propVariant);
			text << L"Get Property  ID:" << m_ribbonInfo->GetCommandNameById(m_currentCommandItemId) << L"  Key Name:" << prop->GetPropertyKeyName() << L"  Value:" << prop->GetPropertyKeyValue() << endl;
		}
		m_pRibbonResultView->AppendText(text.str());
		return S_OK;
	}

	if (nCmdID == cmdSetProperty)
	{
		wostringstream text;
		PROPVARIANT propVariant;
		HRESULT hr = m_pRibbonResultView->SetPropertyValues(m_currentPropertyKey, &propVariant);
		if (SUCCEEDED(hr))
		{
			hr = m_pRibbonResultView->SetUICommandProperty(m_currentCommandItemId, m_currentPropertyKey, propVariant);
				
			if (FAILED(hr))
			{
				text << L"Failed to set propety: " << CPropertyKeyItem::GetPropertyKeyName(m_currentPropertyKey) <<
					L" of command: " << m_ribbonInfo->GetCommandNameById(m_currentCommandItemId) << endl;
			}
			else
			{
				shared_ptr<CProperty> prop = m_propertyReader.Parse(&m_currentPropertyKey, &propVariant);
				text << L"Set Property  ID:" << m_ribbonInfo->GetCommandNameById(m_currentCommandItemId) << L"  Key Name:" << prop->GetPropertyKeyName() << L"  Value:" << prop->GetPropertyKeyValue() << endl;
			}
			m_pRibbonResultView->AppendText(text.str());
			PropVariantClear(&propVariant);
		}
		return S_OK;
	}

	if (nCmdID == cmdSetBooleanValue && verb == UI_EXECUTIONVERB_EXECUTE)
	{
		BOOL bVal;
		UIPropertyToBoolean(UI_PKEY_BooleanValue, *ppropvarValue, &bVal);
		m_currentSetBooleanValue = (bVal == TRUE);
		m_pRibbonResultView->SetSetBooleanValue(m_currentSetBooleanValue);
	}

	if (nCmdID == cmdSetNumericValue && verb == UI_EXECUTIONVERB_EXECUTE)
	{
		DECIMAL dec;
		UIPropertyToDecimal(UI_PKEY_DecimalValue, *ppropvarValue, &dec);
		VarR8FromDec(&dec, &m_currentSetNumericValue);
		m_pRibbonResultView->SetSetNumericValue(m_currentSetNumericValue);
	}

	if (nCmdID == cmdUseSetValues && verb == UI_EXECUTIONVERB_EXECUTE)
	{
		BOOL bVal;
		UIPropertyToBoolean(UI_PKEY_BooleanValue, *ppropvarValue, &bVal);
		m_bUseSetValues = (bVal == TRUE);
		m_pRibbonResultView->SetUseSetValues(m_bUseSetValues);
	}

	if (nCmdID == cmdSetStringValue && verb == UI_EXECUTIONVERB_EXECUTE && *key == UI_PKEY_SelectedItem)
	{
		UINT value;
		UIPropertyToUInt32(UI_PKEY_SelectedItem, *ppropvarValue, &value);
			
		PROPVARIANT text;
		HRESULT hr = E_FAIL;
				
		if (value == UI_COLLECTION_INVALIDINDEX)
		{
			hr = m_pUIFramework->GetUICommandProperty(nCmdID, UI_PKEY_StringValue, &text);
			m_pUIFramework->InvalidateUICommand(nCmdID, UI_INVALIDATIONS_PROPERTY, &UI_PKEY_ItemsSource); //Does not work
		}
		else if (pCommandExecutionProperties != NULL)
		{
			hr = pCommandExecutionProperties->GetValue(UI_PKEY_Label, &text);
		}
				
		if (SUCCEEDED(hr))
		{
			m_currentSetStringValue = text.bstrVal;
			m_pRibbonResultView->SetSetStringValue(m_currentSetStringValue);
			PropVariantClear(&text);
			return S_OK;
		}
	}		
	
	
	if ( CommandRangeContextualTab <= nCmdID && nCmdID < CommandRangeContextPopup)
		ExecuteContextualTabCommand(nCmdID - CommandRangeContextualTab, key, ppropvarValue);
	else if ( CommandRangeContextPopup <= nCmdID && nCmdID < CommandRangeApplicationMode)
		ExecuteContextPopupCommand(nCmdID - CommandRangeContextPopup, key, ppropvarValue);
	else if ( CommandRangeApplicationMode <= nCmdID && nCmdID < CommandRangeEnd)
		ExecuteApplicationModeCommand(nCmdID - CommandRangeApplicationMode, key, ppropvarValue);

	if (nCmdID == cmdSaveState)
	{
		HRESULT hr = m_pRibbonResultView->SaveState();
		if (SUCCEEDED(hr))
		{
			m_bLoadEnabled = true;
			m_pUIFramework->InvalidateUICommand(cmdLoadState, UI_INVALIDATIONS_STATE, NULL);
		}
		return hr;
	}

	if (nCmdID == cmdLoadState)
	{
		return m_pRibbonResultView->LoadState();
	}
	return S_OK;
}

void CRibbonResultManagerView::InitRibbonCommandItem(IUICollection* pCollection, const wstring &commandName)
{
	CComObject<CRibbonCommandItem> *pRibbonCommandItem;
	HRESULT hr = CComObject<CRibbonCommandItem>::CreateInstance(&pRibbonCommandItem);

    if (FAILED(hr))
		return;
	CComPtr<IRibbonCommandItem> ribbonCommand(pRibbonCommandItem);
	ribbonCommand->Initialize(commandName.c_str(), m_ribbonInfo->GetCommandIdByName(commandName));

    pCollection->Add(ribbonCommand);
}

void CRibbonResultManagerView::InitPropertyKeyItem(IUICollection* pCollection, const pair<PROPERTYKEY, wstring> &propertyKeyPair)
{
	CComObject<CPropertyKeyItem> *pPropertyKeyItem;
	HRESULT hr = CComObject<CPropertyKeyItem>::CreateInstance(&pPropertyKeyItem);

    if (FAILED(hr))
		return;
	CComPtr<IPropertyKeyItem> propertyKeyItem(pPropertyKeyItem);
	//initiate the combobox with UI_PKY_* values, skip the UI_PKEY_ h
	propertyKeyItem->Initialize(propertyKeyPair.first, propertyKeyPair.second.substr(8).c_str());

    pCollection->Add(propertyKeyItem);
}


HRESULT CRibbonResultManagerView::UpdateProperty(UINT nCmdID,
		__in REFPROPERTYKEY key,
		__in_opt const PROPVARIANT* ppropvarCurrentValue,
		__out PROPVARIANT* ppropvarNewValue)
{
	HRESULT hr;

	if (nCmdID == cmdCommandSelection)
    {
		if (key == UI_PKEY_ItemsSource)
		{
			IUICollection* pCollection;
			HRESULT hr = ppropvarCurrentValue->punkVal->QueryInterface(IID_PPV_ARGS(&pCollection));
			if (FAILED(hr))
			{
				return hr;
			}

			for_each (m_ribbonInfo->GetCommandNamesCollection().begin(), m_ribbonInfo->GetCommandNamesCollection().end(), bind(&CRibbonResultManagerView::InitRibbonCommandItem, this, pCollection, _1));
			pCollection->Release();
			return S_OK;
		}
		else if (key == UI_PKEY_Categories)
		{
			return S_FALSE;
		}
		else if (key == UI_PKEY_SelectedItem)
		{
			hr = UIInitPropertyFromUInt32(UI_PKEY_SelectedItem, 0, ppropvarNewValue);
			return hr;
		}
	}

	if (nCmdID == cmdPropertyKeySelection)
    {
		if (key == UI_PKEY_ItemsSource)
		{
			IUICollection* pCollection;
			HRESULT hr = ppropvarCurrentValue->punkVal->QueryInterface(IID_PPV_ARGS(&pCollection));
			if (FAILED(hr))
			{
				return hr;
			}

			vector<pair<PROPERTYKEY, wstring>> keyValuePropVector(CPropertyKeyItem::GetPropertyKeyMap().size());
			copy(CPropertyKeyItem::GetPropertyKeyMap().begin(), CPropertyKeyItem::GetPropertyKeyMap().end(), keyValuePropVector.begin());
			sort(keyValuePropVector.begin(), keyValuePropVector.end(), less<pair<PROPERTYKEY, wstring>>());
			for_each(keyValuePropVector.begin(), keyValuePropVector.end(), bind(&CRibbonResultManagerView::InitPropertyKeyItem, this, pCollection, _1));
			pCollection->Release();
			return S_OK;
		}
		else if (key == UI_PKEY_Categories)
		{
			return S_FALSE;
		}
		else if (key == UI_PKEY_SelectedItem)
		{
			hr = UIInitPropertyFromUInt32(UI_PKEY_SelectedItem, 0, ppropvarNewValue);
			return hr;
		}
	}

	if (nCmdID == cmdSetStringValue && key == UI_PKEY_ItemsSource) //does not work
	{
		IUICollection* pCollection;
		HRESULT hr = ppropvarCurrentValue->punkVal->QueryInterface(IID_PPV_ARGS(&pCollection));
		if (FAILED(hr))
		{
			return hr;
		}

		CComObject<CComboBoxTextItem> *pComboBoxItem;
		hr = CComObject<CComboBoxTextItem>::CreateInstance(&pComboBoxItem);
		CComPtr<IComboBoxTextItem> comboBoxItem(pComboBoxItem);
		comboBoxItem->Initialize(m_currentSetStringValue.c_str());
		hr = pCollection->Insert(0, comboBoxItem);
		pCollection->Release();
		
		return hr;
	}

	if (nCmdID == cmdLoadState && key == UI_PKEY_Enabled)
	{
		return UIInitPropertyFromBoolean(UI_PKEY_Enabled, m_bLoadEnabled, ppropvarNewValue);
	}

	return E_FAIL;
}


LRESULT CALLBACK RibbonResultsManagerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
		
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		//switch (wmId)
		//{
		//	default:
				return DefWindowProc(hWnd, message, wParam, lParam);
		//}
		break;

	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		delete CRibbonResultManagerView::s_pRibbonResultManagerView;
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

void CRibbonResultManagerView::RegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= RibbonResultsManagerWndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_RIBBONEXPLORER));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_RIBBONEXPLORER);
	wcex.lpszClassName	= RIBBONRESULTMANAGERVIEW_WNDCLASS;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_RIBBONEXPLORER));
	RegisterClassEx(&wcex);
}


wstring CRibbonResultManagerView::GenerateResultManagerRibbon()
{
	wostringstream text;
	
	WRITE_LINE(text, L"<?xml version=\"1.0\" encoding=\"utf-8\"?>");
	WRITE_LINE(text, L"<Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>");
	WRITE_LINE(text, L"	<Application.Commands>");
	WRITE_LINE(text, L"	    <Command Name='cmdHomeTab' LabelTitle='Home'/>");
	WRITE_LINE(text, L"	    <Command Name='cmdInvalidateSetTab' LabelTitle='Invalidate &amp;&amp; Set'/>");
	WRITE_LINE(text, L"     <Command Name='cmdCommandGroup' Keytip='G' LabelTitle='Invalidate Commands'/>");
    WRITE_LINE(text, L"     <Command Name='cmdCommandSelection' Id='12345' Keytip='M' LabelTitle='Command:' TooltipTitle='Choose Command'/>");
	cmdCommandSelection = 12345;
	WRITE_LINE(text, L"     <Command Name='cmdPropertyKeySelection'  Id='12346' Keytip='K' LabelTitle='Property Key:' TooltipTitle='Choose property key'/>");
	cmdPropertyKeySelection = 12346;
    WRITE_LINE(text, L"     <Command Name='cmdInvalidateState' Id='12347' Keytip='S' LabelTitle='Invalidate State' TooltipTitle='Invalidate the selected command state'/>");
	cmdInvalidateState = 12347;
    WRITE_LINE(text, L"     <Command Name='cmdInvalidateValue' Id='12348' Keytip='V' LabelTitle='Invalidate Value' TooltipTitle='Invalidate the selected command value'/>");
	cmdInvalidateValue = 12348;
    WRITE_LINE(text, L"     <Command Name='cmdInvalidateProperty' Id='12349' Keytip='P' LabelTitle='Invalidate Property' TooltipTitle='Invalidate the selected command property'/>");
	cmdInvalidateProperty = 12349;
    WRITE_LINE(text, L"     <Command Name='cmdInvalidateAllProperty' Id='12350' Keytip='A' LabelTitle='Invalidate All Properties' TooltipTitle='Invalidate the selected command properties'/>");
	cmdInvalidateAllProperty = 12350;
    WRITE_LINE(text, L"     <Command Name='cmdGetProperty' Id='12351' Keytip='O' LabelTitle='Get Property' TooltipTitle='Get a command property value directly'/>");
	cmdGetProperty = 12351;
	WRITE_LINE(text, L"     <Command Name='cmdSetProperty' Id='12352' Keytip='R' LabelTitle='Set Property' TooltipTitle='Set a command property value directly'/>");
	cmdSetProperty = 12352;
	WRITE_LINE(text, L"     <Command Name='cmdSetStringValue'  Id='12353' Keytip='SV' LabelTitle='Set String Value:' TooltipTitle='Use this text to set the invalidate text property'/>");
	cmdSetStringValue = 12353;
    WRITE_LINE(text, L"     <Command Name='cmdSetNumericValue'  Id='12354' Keytip='NV' LabelTitle='Set numeric Value:' TooltipTitle='Use this number to set the invalidate number property'/>");
	cmdSetNumericValue = 12354;
    WRITE_LINE(text, L"     <Command Name='cmdSetBooleanValue'  Id='12355' Keytip='BV' LabelTitle='Set boolean Value' TooltipTitle='Use this boolean to set the invalidate boolean property'/>");
	cmdSetBooleanValue = 12355;
	WRITE_LINE(text, L"		<Command Name='cmdUseSetValues' Id='12356' Keytip='U' LabelTitle='Set Values On Invalidate' TooltipTitle='Set a new value for the invalidated control'/>");
	cmdUseSetValues = 12356;
	WRITE_LINE(text, L"		<Command Name='cmdGrpState' Keytip='A' LabelTitle='Save/Load The Ribbon State' TooltipTitle='Save or load the ribbon state'/>");
	WRITE_LINE(text, L"		<Command Name='cmdSaveState' Id='12357' Keytip='S' LabelTitle='Save' TooltipTitle='Save the ribbon state'/>");
	cmdSaveState = 12357;
	WRITE_LINE(text, L"		<Command Name='cmdLoadState' Id='12358' Keytip='L' LabelTitle='Load' TooltipTitle='Load the ribbon state'/>");
	cmdLoadState = 12358;
	WRITE_LINE(text, L"		<Command Name='cmdColorGrp' Keytip='CG' LabelTitle='Ribbon Colors'/>");
    WRITE_LINE(text, L"		<Command Name='cmdBackgroundColor' Id='12359'  Keytip='B' LabelTitle='Background Color' TooltipTitle='Change the background color of the Ribbon'/>");
	cmdBackgroundColor = 12359;
    WRITE_LINE(text, L"		<Command Name='cmdHighlightColor' Id='12360' Keytip='I' LabelTitle='Highlight Color' TooltipTitle='Change the Ribbon Highlight Color'/>");
	cmdHighlightColor = 12360;
    WRITE_LINE(text, L"		<Command Name='cmdTextColor' Id='12361' Keytip='T' LabelTitle='Text Color' TooltipTitle='Change the Ribbon Text Color'/>");
	cmdTextColor = 12361;
	WRITE_LINE(text, L"		<Command Name='cmdAppMenu' LabelTitle='Application Menu'/>");
	WRITE_LINE(text, L"		<Command Name='cmdApplicationModeDropDwonButton' LabelTitle='Application Modes'/>");
	WRITE_LINE(text, L"		<Command Name='cmdContextualTabsDropDownButton' LabelTitle='Contextual Tabs'/>");
	WRITE_LINE(text, L"		<Command Name='cmdContextPopupDropDownButton' LabelTitle='Context Popups'/>");
	WRITE_LINE(text, L"		<Command Name='cmdGrpContextPopup' LabelTitle='Context Popups'/>");
	WRITE_LINE(text, L"		<Command Name='cmdGrpContextualTabs' LabelTitle='Contextual Tabs'/>");
	WRITE_LINE(text, L"		<Command Name='cmdGrpApplicationMode' LabelTitle='Application Modes'/>");

	
	GenerateApplicationModeCommands(text);
	
	GenerateCommands(text, m_ribbonInfo->GetCommandIdsForContextualTabs(), 
		L"cmdContextualTab", CommandRangeContextualTab);
				
	GenerateCommands(text, m_ribbonInfo->GetCommandIdsForContextPopup(), 
		L"cmdContextPopup", CommandRangeContextPopup);
	
	WRITE_LINE(text, L"	</Application.Commands>");
	WRITE_LINE(text, L"	<Application.Views>");
	WRITE_LINE(text, L"		<Ribbon>");
	WRITE_LINE(text, L"			<Ribbon.ApplicationMenu>");
    WRITE_LINE(text, L"				<ApplicationMenu CommandName='cmdAppMenu'>");
	if (m_ribbonInfo->GetCommandIdsForContextPopup().size() > 0)
	{
		WRITE_LINE(text, L"					<MenuGroup>");
		GenerateContextPopupDropDownButton(text);
		WRITE_LINE(text, L"					</MenuGroup>");
	}
	
	if (m_ribbonInfo->GetCommandIdsForContextualTabs().size() > 0)
	{
		WRITE_LINE(text, L"					<MenuGroup>");
		WRITE_LINE(text, L"						<DropDownButton CommandName='cmdContextualTabsDropDownButton'>");
		GenerateContextualTabCheckBoxButtons(text);
		WRITE_LINE(text, L"						</DropDownButton>");
	    WRITE_LINE(text, L"					</MenuGroup>");

	}

	if (m_ribbonInfo->GetApplicationModes().size() > 1)
	{
		WRITE_LINE(text, L"					<MenuGroup>");
		WRITE_LINE(text, L"						<DropDownButton CommandName='cmdApplicationModeDropDwonButton'>");
		GenerateApplicationModeCheckBoxButtons(text);
		WRITE_LINE(text, L"						</DropDownButton>");
	    WRITE_LINE(text, L"					</MenuGroup>");

	}
	WRITE_LINE(text, L"				</ApplicationMenu>");
	WRITE_LINE(text, L"			</Ribbon.ApplicationMenu>");
	WRITE_LINE(text, L"			<Ribbon.Tabs>");
    WRITE_LINE(text, L"				<Tab CommandName='cmdHomeTab'>");
   
	if (m_ribbonInfo->GetCommandIdsForContextPopup().size() > 0)
	{
	    WRITE_LINE(text, L"					<Group CommandName='cmdGrpContextPopup'>");
		GenerateContextPopupDropDownButton(text);
	    WRITE_LINE(text, L"					</Group>");

	}

	if (m_ribbonInfo->GetCommandIdsForContextualTabs().size() > 0)
	{
		WRITE_LINE(text, L"						<Group CommandName='cmdGrpContextualTabs'>");
		GenerateContextualTabCheckBoxButtons(text);
	    WRITE_LINE(text, L"						</Group>");
	}

	if (m_ribbonInfo->GetApplicationModes().size() > 1)
	{
		WRITE_LINE(text, L"						<Group CommandName='cmdGrpApplicationMode'>");
		GenerateApplicationModeCheckBoxButtons(text);
	    WRITE_LINE(text, L"						</Group>");
	}
	WRITE_LINE(text, L"                 <Group CommandName='cmdGrpState' SizeDefinition='TwoButtons'>");
	WRITE_LINE(text, L"                     <Button CommandName='cmdLoadState'/>");
	WRITE_LINE(text, L"                     <Button CommandName='cmdSaveState'/>");
	WRITE_LINE(text, L"                 </Group>");
	WRITE_LINE(text, L"                 <Group CommandName='cmdColorGrp' SizeDefinition='ThreeButtons'>");
    WRITE_LINE(text, L"                     <DropDownColorPicker CommandName='cmdBackgroundColor' ChipSize='Small' ColorTemplate='ThemeColors' IsNoColorButtonVisible='false'/>");
    WRITE_LINE(text, L"                     <DropDownColorPicker CommandName='cmdHighlightColor' ChipSize='Small' ColorTemplate='ThemeColors' IsNoColorButtonVisible='false'/>");
    WRITE_LINE(text, L"                     <DropDownColorPicker CommandName='cmdTextColor' ChipSize='Small' ColorTemplate='ThemeColors' IsNoColorButtonVisible='false'/>");
    WRITE_LINE(text, L"                 </Group>");
    WRITE_LINE(text, L"				</Tab>");
	WRITE_LINE(text, L"				<Tab CommandName='cmdInvalidateSetTab'>");
	WRITE_LINE(text, L"                 <Group CommandName='cmdCommandGroup'>");
	WRITE_LINE(text, L"                 <SizeDefinition>");
    WRITE_LINE(text, L"                   <ControlNameMap>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdCommandSelection'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdPropertyKeySelection'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdInvalidateAllProperty'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdInvalidateValue'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdInvalidateState'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdInvalidateProperty'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdGetProperty'/>");
	WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdSetProperty'/>");
	WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdUseSetValues'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdSetStringValue'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdSetNumericValue'/>");
    WRITE_LINE(text, L"                     <ControlNameDefinition Name='cmdSetBooleanValue'/>");
    WRITE_LINE(text, L"                   </ControlNameMap>");
    WRITE_LINE(text, L"                   <GroupSizeDefinition Size='Large'>");
    WRITE_LINE(text, L"                     <Row>");
    WRITE_LINE(text, L"                       <ControlSizeDefinition ControlName='cmdCommandSelection' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                       <ControlSizeDefinition ControlName='cmdPropertyKeySelection' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                     </Row>");
    WRITE_LINE(text, L"                     <Row>");
    WRITE_LINE(text, L"                       <ControlGroup>");
    WRITE_LINE(text, L"                         <ControlSizeDefinition ControlName='cmdInvalidateAllProperty' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                         <ControlSizeDefinition ControlName='cmdInvalidateState' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                         <ControlSizeDefinition ControlName='cmdInvalidateValue' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                         <ControlSizeDefinition ControlName='cmdInvalidateProperty' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                       </ControlGroup>");
    WRITE_LINE(text, L"                     </Row>");
	WRITE_LINE(text, L"                     <Row>");
	WRITE_LINE(text, L"                         <ControlGroup>");
	WRITE_LINE(text, L"                           <ControlSizeDefinition ControlName='cmdGetProperty' IsLabelVisible='true'/>");
	WRITE_LINE(text, L"                           <ControlSizeDefinition ControlName='cmdSetProperty' IsLabelVisible='true'/>");
	WRITE_LINE(text, L"                         </ControlGroup>");
	WRITE_LINE(text, L"                         <ControlSizeDefinition ControlName='cmdUseSetValues' IsLabelVisible='true'/>");
	WRITE_LINE(text, L"                     </Row>");
    WRITE_LINE(text, L"                     <ColumnBreak/>");
    WRITE_LINE(text, L"                     <ControlSizeDefinition ControlName='cmdSetStringValue' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                     <ControlSizeDefinition ControlName='cmdSetNumericValue' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                     <ControlSizeDefinition ControlName='cmdSetBooleanValue' IsLabelVisible='true'/>");
    WRITE_LINE(text, L"                   </GroupSizeDefinition>");
    WRITE_LINE(text, L"                 </SizeDefinition>");
    WRITE_LINE(text, L"                     <ComboBox CommandName='cmdCommandSelection' IsEditable='false' IsAutoCompleteEnabled='true' ResizeType='VerticalResize'/>");
    WRITE_LINE(text, L"                     <ComboBox CommandName='cmdPropertyKeySelection' IsEditable='false' IsAutoCompleteEnabled='true' ResizeType='VerticalResize'/>");
	WRITE_LINE(text, L"                     <Button CommandName='cmdInvalidateAllProperty'/>");
    WRITE_LINE(text, L"                     <Button CommandName='cmdInvalidateState'/>");
    WRITE_LINE(text, L"                     <Button CommandName='cmdInvalidateValue'/>");
    WRITE_LINE(text, L"                     <Button CommandName='cmdInvalidateProperty'/>");
    WRITE_LINE(text, L"                     <Button CommandName='cmdGetProperty'/>");
	WRITE_LINE(text, L"                     <Button CommandName='cmdSetProperty'/>");
	WRITE_LINE(text, L"                     <ToggleButton CommandName='cmdUseSetValues'/>");
	WRITE_LINE(text, L"                     <ComboBox CommandName='cmdSetStringValue' IsEditable='true' IsAutoCompleteEnabled='true' ResizeType='NoResize'/>");
    WRITE_LINE(text, L"                     <Spinner CommandName='cmdSetNumericValue'/>");
    WRITE_LINE(text, L"                     <CheckBox CommandName='cmdSetBooleanValue'/>");
    WRITE_LINE(text, L"                 </Group>");
	WRITE_LINE(text, L"				</Tab>");
	WRITE_LINE(text, L"			</Ribbon.Tabs>");
	WRITE_LINE(text, L"		</Ribbon>");
	WRITE_LINE(text, L"	</Application.Views>");
	WRITE_LINE(text, L"</Application>");

	wstring resultManagerRibbonFilePath = CUtil::GetTempFilePath(L"xml");
	CUtil::WriteFileText(resultManagerRibbonFilePath, text.str()); 
	
	CRibbonCompiler ribbonCompiler(resultManagerRibbonFilePath, g_sUICCPath, g_sRCPath, g_sLINKPath);
	wstring resultManagerRibbonDll = CUtil::GetTempFilePath(L"dll");
	ribbonCompiler.Compile(resultManagerRibbonDll);

	return resultManagerRibbonDll;
}

void CRibbonResultManagerView::GenerateCommands(wostringstream &text,
												const vector<int> &v, const wstring &prefix,
												int rangeStart)
{
	for (vector<int>::const_iterator iter = v.begin(); iter != v.end();	++iter)
	{
		text << L"		<Command Name='" << prefix << *iter 
			 << L"' Id ='" << rangeStart + *iter << L"' LabelTitle='" 
			 << m_ribbonInfo->GetCommandNameById(*iter) << "'/>" << endl;
	}
}


void CRibbonResultManagerView::GenerateApplicationModeCommands(wostringstream &text)
{
	const vector<int> &v = m_ribbonInfo->GetApplicationModes();
	for (vector<int>::const_iterator iter = v.begin(); iter != v.end();	++iter)
	{
		text << L"		<Command Name='cmdApplicationMode" << *iter 
			 << L"' Id ='" << CommandRangeApplicationMode + *iter << L"' LabelTitle='" 
			 << L"Mode " << *iter << "'/>" << endl;
	}
}

void CRibbonResultManagerView::GenerateContextPopupDropDownButton(wostringstream &text)
{
	WRITE_LINE(text, L"		<DropDownButton CommandName='cmdContextPopupDropDownButton'>");

	const vector<int> &v = m_ribbonInfo->GetCommandIdsForContextPopup();
	for (vector<int>::const_iterator iter = v.begin(); iter != v.end();	++iter)
	{
		text << L"			<Button CommandName='" << L"cmdContextPopup" <<
			*iter << L"' />" << endl;
	}
   	WRITE_LINE(text, L"		</DropDownButton>");
}

void CRibbonResultManagerView::GenerateContextualTabCheckBoxButtons(wostringstream &text)
{
	const vector<int> &v = m_ribbonInfo->GetCommandIdsForContextualTabs();
	for (vector<int>::const_iterator iter = v.begin(); iter != v.end();	++iter)
	{
		text << L"			<CheckBox CommandName='" << L"cmdContextualTab" <<
			*iter << L"' />" << endl;
	}
}

void CRibbonResultManagerView::GenerateApplicationModeCheckBoxButtons(wostringstream &text)
{
	const vector<int> &v = m_ribbonInfo->GetApplicationModes();
	for (vector<int>::const_iterator iter = v.begin(); iter != v.end();	++iter)
	{
		text << L"			<CheckBox CommandName='" << L"cmdApplicationMode" <<
			*iter << L"' />" << endl;
	}
}

void CRibbonResultManagerView::ExecuteContextualTabCommand(int nCmdID, const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue)
{
	BOOL val;
	UIPropertyToBoolean(*key, *ppropvarValue, &val);
	
	m_pRibbonResultView->ShowContextualTab(nCmdID, val ? UI_CONTEXTAVAILABILITY_ACTIVE : UI_CONTEXTAVAILABILITY_NOTAVAILABLE); 
}

void CRibbonResultManagerView::ExecuteContextPopupCommand(int nCmdID, const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue)
{
	m_pRibbonResultView->ShowContextMenu(nCmdID);
}

void CRibbonResultManagerView::ExecuteApplicationModeCommand(int nCmdID, const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue)
{
	BOOL val;
	UIPropertyToBoolean(*key, *ppropvarValue, &val);
	INT32 mode = UI_MAKEAPPMODE(nCmdID);
	if (val)
	{
		m_currentApplicationMode |= mode;
	}
	else
	{
		m_currentApplicationMode &= ~mode;
	}

	m_pRibbonResultView->SetApplicationMode(m_currentApplicationMode);
}
